<template>
  <a-card class="atom-list" :bordered="false">
    <!-- 标题 -->
    <template v-if="title" #title>
      <FuncTitle :title="title"></FuncTitle>
    </template>
    <!-- 右侧功能按钮 -->
    <template v-if="funcZone" #extra>
      <FuncZone ref="funcZone"
                :funcZone="funcZone"
                :checkedCount="selectedRowKeys.length"
                @func-zone-action="handleFuncAction"
                @func-zone-checkall="handleFuncCheckAll"
                @func-zone-clear-check="handleFuncClearCheck">
      </FuncZone>
    </template>
    <a-checkbox-group v-model:value="selectedRowKeys" @change="handleSelectChange">
      <!-- 列表 -->
      <a-list v-bind="$attrs"
              :grid="metaType === 'card' ? grid || { gutter: 16, column: 4 } : grid"
              :dataSource="dataSource"
              :pagination="listPagination"
              :loading="loading">
        <!-- 是否有加载更多，pagination优先级更高 -->
        <template v-if="loadMore" #loadMore>
          <a class="atom-list-load-more" @click="handleLoadMore">
            {{ hasMore ? (loading ? '加载中...' : '加载更多') : '~已经到底了~' }}
          </a>
        </template>
        <template #renderItem="{ item, index }">
          <!-- list展示形式 -->
          <a-list-item v-if="metaType === 'list'">
            <!-- item索引部分 -->
            <a-list-item-meta :class="columnFields.description ? '' : 'no-description'">
              <!-- 头像  -->
              <template v-if="columnFields.avatar || checkable" #avatar>
                <a-checkbox v-if="checkable" :value="item[columnFields.key.dataIndex] || index"/>
                <!-- 如果没有avatar时，则将checkbox作为avatar  -->
                <a-avatar v-if="columnFields.avatar"
                          :src="item[columnFields.avatar.dataIndex]">
                  {{ (item[columnFields.title.dataIndex] && item[columnFields.title.dataIndex].charAt(0)) || '' }}
                </a-avatar>
              </template>
              <!-- 标题  -->
              <template v-if="columnFields.title" #title>
                <a @click="handleTitleLink(item)">
                  <CellRender :column="columnFields.title"
                              :text="item[columnFields.title.dataIndex]"
                              :row="item"
                              :index="index"></CellRender>
                </a>
              </template>
              <!-- 描述  -->
              <template v-if="columnFields.description" #description>
                <CellRender :column="columnFields.description"
                            :text="item[columnFields.description.dataIndex]"
                            :row="item"
                            :index="index"></CellRender>
              </template>
            </a-list-item-meta>
            <!-- item内容 -->
            <div v-if="columnFields.content" class="atom-list-item-content">
              <CellRender :column="columnFields.content"
                          :text="item[columnFields.content.dataIndex]"
                          :row="item"
                          :index="index"></CellRender>
            </div>
            <!-- item extra -->
            <template v-if="columnFields.cover" #extra>
              <a-image :width="columnFields.cover.width || 120"
                       :src="item[columnFields.cover.dataIndex]"
                       fallback="" />
            </template>
            <!-- 扩展操作 -->
            <template v-if="columnFields.actions" #actions>
              <CellRender :column="columnFields.actions"
                          :row="item"
                          :index="index"
                          @cell-action="handleRowAction"></CellRender>
            </template>
          </a-list-item>
          <!-- card展示方式 -->
          <a-list-item v-else-if="metaType === 'card'">
            <a-card hoverable @click="handleTitleLink(item, index)"
                    :class="[checkable && selectedRowKeys.includes(item[columnFields.key.dataIndex]) ? 'checked' : '']">
              <template v-if="columnFields.cover" #cover>
                <a-image :width="columnFields.cover.width"
                         :src="item[columnFields.cover.dataIndex]"
                         fallback="" />
              </template>
              <!-- 扩展操作 -->
              <template v-if="columnFields.actions" #actions>
                <CellRender v-for="(action, idx) in columnFields.actions.actions"
                            :key="idx"
                            :column="{ ...columnFields.actions, action }"
                            :row="item"
                            :index="index"
                            @cell-action="handleRowAction"></CellRender>
              </template>
              <!-- card meta -->
              <a-card-meta :class="columnFields.description ? '' : 'no-description'">
                <!-- 头像  -->
                <template v-if="columnFields.avatar" #avatar>
                  <!-- 如果没有avatar时，则将checkbox作为avatar  -->
                  <a-avatar v-if="columnFields.avatar"
                            :src="item[columnFields.avatar.dataIndex]">
                    {{ (item[columnFields.title.dataIndex] && item[columnFields.title.dataIndex].charAt(0)) || '' }}
                  </a-avatar>
                </template>
                <!-- 标题  -->
                <template v-if="columnFields.title" #title>
                  <CellRender :column="columnFields.title"
                              :text="item[columnFields.title.dataIndex]"
                              :row="item"
                              :index="index"></CellRender>
                </template>
                <!-- 描述  -->
                <template v-if="columnFields.description" #description>
                  <CellRender :column="columnFields.description"
                              :text="item[columnFields.description.dataIndex]"
                              :row="item"
                              :index="index"></CellRender>
                </template>
              </a-card-meta>
            </a-card>
          </a-list-item>
        </template>
      </a-list>
    </a-checkbox-group>
  </a-card>
</template>

<script>
/**
 * 格式化列表 TODO 增加ListCard展示类型
 * 可处理的字段如下：
 * { key: 'id', avatar: 'avatar', title: 'title', description: 'description', content: 'content', cover: 'cover' }
 * 采用cover的原因是为了兼容ListCard中的封面，与ListMeta中的extra相对应
 * title: 列表标题
 * meta: 列表的展示形式 list | card
 * grid: 列表的布局网格
 * dataSource: 数据列表
 * pagination: 分页信息
 * loadMore: 加载更多与pagination互斥，pagination优先级高
 * 其他字段参考FormatTable相关描述
 */
import FuncTitle from '@/components/Common/FuncTitle'
import FuncZone from '@/components/Common/FuncZone'
import { CellRender } from '@/components/Common/Render'
export default {
  name: 'FormatList',
  components: { FuncTitle, FuncZone, CellRender },
  props: {
    // 列表标题
    title: {
      type: [String, Boolean],
      required: false
    },
    // meta的展示形式 list | card
    metaType: {
      type: String,
      default: 'list'
    },
    // card模式的宽度
    grid: {
      type: Object,
      required: false
    },
    // 数据列表
    dataSource: {
      type: Array,
      required: false
    },
    /**
     * 字段列表 { key, title, dataIndex, span, class, format, form }
     * key: 为固定的list-meta所对应的字段
     * title: 表示对应的FormatList中fieldKeys被替换的key
     * dataIndex: 表示字段属性名
     * 其他与FormTable中完全一致
     */
    columns: {
      type: Array,
      required: true
    },
    // 分页信息
    pagination: {
      type: [Object, Boolean],
      default: () => ({ current: 1, pageSize: 10, total: 0, showSizeChanger: true })
    },
    // 是否展示加载更多，与pagination互斥，loadMore优先级高
    loadMore: {
      type: Boolean,
      default: false
    },
    // 是否还有更多数据
    hasMore: {
      type: Boolean,
      default: true
    },
    // 顶部右侧功能按钮区
    funcZone: {
      type: Object,
      required: false
    },
    // 是否加载中
    loading: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      // 是否可选择
      checkable: false,
      // 列表分页
      listPagination: false,
      // 选中的行keys
      selectedRowKeys: [],
      // 选中的行
      selectedRows: []
    }
  },
  computed: {
    /**
     * 字段列对象，通过columns转换
     * 字段key值，需要用到哪个展示就填写其字段
     * extra默认为图片内容
     * { key: 'id', avatar: 'avatar', title: 'title', description: 'description', content: 'content', cover: 'cover' }
     */
    columnFields () {
      const columnFields = {}
      this.columns.forEach(column => {
        columnFields[column.key] = column
      })
      // 兼容key值不指定的情况
      if (!columnFields['key']) {
        columnFields['key'] = {}
      }
      return columnFields
    }
  },
  emits: ['list-func-action', 'list-load-more', 'list-row-selection', 'list-row-action'],
  methods: {
    // 响应标题跳转，扩展成行动作
    handleTitleLink (row, index) {
      if (this.checkable) {
        const rowKey = row[this.columnFields.key.dataIndex] || index
        const keyIndex = this.selectedRowKeys.indexOf(rowKey)
        if (keyIndex > -1) {
          this.selectedRowKeys.splice(keyIndex, 1)
        } else {
          this.selectedRowKeys.push(rowKey)
        }
        this.handleSelectChange()
      }
      this.$emit('list-row-action', { name: 'link', extend: true }, row)
    },
    /**
     * 响应功能区域操作按钮
     * @param action 响应事件的名称
     * @param extend 是否扩展功能，true | false，true事件直接上抛不做默认处理
     * @param checkable 是否可选择
     */
    handleFuncAction (action, extend, checkable) {
      // 开启或者取消选择
      if (action.name === this.$default.ACTION.CHECK.name) {
        this.checkable = checkable
        // 是否可选择切换时将选中结果切换掉
        this.selectedRowKeys = []
        this.selectedRows = []
      } else {
        this.$emit('list-func-action', action, extend)
      }
    },
    // 响应选中的变化
    handleSelectChange () {
      this.selectedRows = this.dataSource.filter((data, index) => this.selectedRowKeys.includes(data[this.columnFields.key.dataIndex] || index))
      // 修改全选状态
      this.$refs.funcZone.checkall = !(this.selectedRowKeys.length < this.dataSource.length)
      this.$emit('list-row-selection', this.selectedRowKeys, this.selectedRows)
    },
    // 响应全选与否
    handleFuncCheckAll (checkAll) {
      if (checkAll) {
        this.selectedRowKeys = this.dataSource.map((data, index) => data[this.columnFields.key.dataIndex] || index)
        this.selectedRows = this.dataSource
      } else {
        this.selectedRowKeys = []
        this.selectedRows = []
      }
      this.$emit('list-row-selection', this.selectedRowKeys, this.selectedRows)
    },
    // 响应清除选择
    handleFuncClearCheck () {
      this.selectedRowKeys = []
      this.selectedRows = []
      this.$emit('list-row-selection', [], [])
    },
    // 响应扩展操作
    handleRowAction (action, row) {
      this.$emit('list-row-action', action, row)
    },
    // 响应加载更多
    handleLoadMore () {
      if (this.hasMore) {
        this.$emit('list-load-more')
      } else {
        this.$message.warn('没有更多数据！')
      }
    }
  }
}
</script>

<style lang="less">
@import "FormatList";
</style>
